#include <cmath>

#include "plotsettings.h"


//////////////////////////////////////////////////////////////////////////////
PlotSettings::PlotSettings()
{
    minX = 0.0;
    maxX = 8.0;

    minY = 0;
    maxY = 2;

    numXTicks = 20;
    numYTicks = 20;
}



//////////////////////////////////////////////////////////////////////////////
void PlotSettings::scroll(int dx, int dy)
{
    // Se calcula el tamaño de una marca del eje X
    double stepX = spanX() / numXTicks;

    // Desplazar minX y maxX en dx marcas
    minX = minX + dx*stepX;
    maxX = maxX + dx*stepX;

    // Se calcula el tamaño de una marca del eje Y
    double stepY = spanY() / numYTicks;

    // Desplazar minY y maxY en dy marcas
    minY = minY + dy*stepY;
    maxY = maxY + dy*stepY;
}



//////////////////////////////////////////////////////////////////////////////
void PlotSettings::adjust()
{
    // Ajusta valores para el eje X
    adjustAxis(minX, maxX, numXTicks);

    // Ajusta valores para el eje Y
    adjustAxis(minY, maxY, numYTicks);
}



//////////////////////////////////////////////////////////////////////////////
void PlotSettings::adjustAxis(double &min, double &max, int &numTicks)
{
    // Un algoritmo bastante mas sofisticado para hacer esto se describe en
    // el libro "Nice numbers for graph labels". De momento no vamos a darle
    // mas importancia, es un metodo bastante complejo

    // Numero minimo de marcas en el eje
    const int MinTicks = 4;

    // Es una especie de maximo para el step
    double grossStep = (max - min) / MinTicks;

    double step = pow(10.0, floor(log10(grossStep)));

    if (5 * step < grossStep)
        step *= 5;
    else if (2 * step < grossStep)
        step *= 2;

    // floor(x) devuelve parte_entera(x) si x>0 y parte_entera(x-1) si x<0 trunc
    numTicks = (int)(ceil(max / step) - floor(min / step));

    if (numTicks < MinTicks)
        numTicks = MinTicks;

    min = floor(min / step) * step;
    max = ceil(max / step) * step;
}







